/***************************************************************************
 *   smd.c - SMD File Loader                                               *
 *   Copyright (C) 2008 by cmaster.matso                                   *
 *   cmaster.matso@gmail.com                                               *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "smd.h"

/* TODO: */

static char line_buffer[128]; /* ???? */

/**
 *
 */
static SDL_Surface *load_texture(const char *tex_name) {
    return (SDL_Surface *) IMG_Load(tex_name); /* ???? */
}

/**
 *
 */
static GLuint make_texture(SDL_Surface *tex_surface) {
    GLuint tex_id;
    glGenTextures(1, &tex_id);
    glBindTexture(GL_TEXTURE_2D, tex_id);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

    gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, tex_surface->w, tex_surface->h,
            GL_RGBA, GL_UNSIGNED_BYTE, tex_surface->pixels);
    return tex_id;
}

/**
 *
 */
static int get_num_bones(FILE *fp)/* use fseek() */ {
    int num_bones;
    /* TODO: ... */
    return num_bones;
}

/**
 *
 */
static int get_num_poses(FILE *fp) {
    int num_poses;
    /* TODO: ... */
    return num_poses;
}

/**
 *
 */
static int get_num_triangles(FILE *fp) {
    int num_triangles;
    /* TODO: ... */
    return num_triangles;
}

/**
 *
 */
static void next_line(FILE *fp) {
    fgets(line_buffer, 128, fp);
    return;
}

/**
 *
 */
void gsubReadSMDModel(const char *file_path, smd_model_t *mdl)/* ?????????????/ */ {
    FILE *fp = NULL;
    char string[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* !!!! inaczej !!!! */
    int i;

    if (!mdl) {
        MGPI_PostMessage("readSMDModel: first allocate the model pointer", fp);
        return;
    }

    if (!(fp = fopen(file_path, "rt"))) {
        sprintf(string, "readSMDModel: No such file or directory: %s", file_path); /* zrobi� w innych podobnie */
        MGPI_PostMessage(string, fp); /* ??? */
        return;
    }

    sprintf(string, "%s %%d", SMD_VERSION); /* kwestia bia�ych znak�w */
    fscanf(fp, string, &mdl->version); /* format? */
    if (mdl->version != HL_MODEL_VERSION) {
        MGPI_PostMessage("readSMDModel: wrong version of the file", fp);
        fclose(fp);
        fp = NULL;
        return;
    }

    if ((mdl->num_bones = get_num_bones(fp)) <= 0 ||
            (mdl->num_poses = get_num_poses(fp)) <= 0 ||
            (mdl->num_triangles = get_num_triangles(fp)) <= 0) {
        MGPI_PostMessage("readSMDModel: wrong data in file - cannot process forward", fp);
        fclose(fp);
        fp = NULL;
        return;
    }
    mdl->num_vertices = 3 * mdl->num_triangles;

    next_line(fp); /* zak�adaj�c �e w powy�szych funkcjach wracamy na pocz�tek pliku za pomoc� fseek() */
    next_line(fp);

    mdl->model_bones = (struct _smd_bone *) calloc(mdl->num_bones, sizeof (struct _smd_bone));
    mdl->model_poses = (struct _smd_pose *) calloc(mdl->num_poses, sizeof (struct _smd_pose));
    mdl->model_triangles = (struct _smd_triangle *) calloc(mdl->num_triangles, sizeof (struct _smd_triangle)); /*???????*/
    mdl->model_vertices = (struct _smd_vertex *) calloc(mdl->num_vertices, sizeof (struct _smd_vertex));
    mdl->vta_model_vertices = (struct _vta_vertex *) calloc(mdl->num_vertices, sizeof (struct _vta_vertex)); /* co z tymi wierzcho�kami? */

    if (!strstr(line_buffer, SMD_NODES)) {
        MGPI_PostMessage("readSMDModel: inappropriate tag in the file", fp);
        fclose(fp);
        fp = NULL;
        return;
    }

    for (i = 0; i < mdl->num_bones; ++i)
        fscanf(fp, "%d \"%s\" %d", &mdl->model_bones[i].id, mdl->model_bones[i].name, &mdl->model_bones[i].parent_id); /* format? */
    next_line(fp);

    if (!strstr(line_buffer, SMD_END)) {
        MGPI_PostMessage("readSMDModel: inappropriate tag in the file", fp);
        fclose(fp);
        fp = NULL;
        return;
    }

    next_line(fp);
    for (i = 0; i < mdl->num_poses; ++i) {
        next_line(fp);
        if (!strstr(line_buffer, SMD_TIME)) {
            MGPI_PostMessage("readSMDModel: inappropriate tag in the file", fp);
            fclose(fp);
            fp = NULL;
            return;
        }
        fscanf(fp, "%d %f %f %f %f %f %f", /* format? */
                &mdl->model_poses[i].bone_id,
                &mdl->model_poses[i].position[X], &mdl->model_poses[i].position[Y], &mdl->model_poses[i].position[Z],
                &mdl->model_poses[i].rotation[X], &mdl->model_poses[i].rotation[Y], &mdl->model_poses[i].rotation[Z]);
    }
    next_line(fp);

    if (!strstr(line_buffer, SMD_END)) {
        MGPI_PostMessage("readSMDModel: inappropriate tag in the file", fp);
        fclose(fp);
        fp = NULL;
        return;
    }

    /* TODO:
       1. triangles section;
       2. VTA section;
       3. vertex calculations; (czy napewno tutaj?)*/

    fclose(fp);

    return;
}

/**
 *
 */
void gsubFreeSMDModel(smd_model_t *mdl) {
    /* TODO: ... */
    return;
}

/**
 *
 */
void gsubRenderSMDModel(smd_model_t *mdl) {
    /* TODO: ... */
    return;
}

/**
 *
 */
void gsubAnimateSMD(smd_model_t *mdl) {
    /* TODO: ... */
    return;
}
